home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 52 / Amiga Format AFCD52 (Issue 136, May 2000).iso / -serious- / programming / other / jikes-1.11 / src / op.cpp < prev    next >
C/C++ Source or Header  |  2000-02-23  |  27KB  |  784 lines

  1. // $Id: op.cpp,v 1.6 1999/08/26 15:34:09 shields Exp $
  2. //
  3. // This software is subject to the terms of the IBM Jikes Compiler
  4. // License Agreement available at the following URL:
  5. // http://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10. #include "config.h"
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <iostream.h>
  14. #include <string.h>
  15. #include "op.h"
  16.  
  17. void Operators::opdesc(int opc, char **name, char **desc)
  18. {
  19.     struct op_entry
  20.     {
  21.         char *op_name,
  22.              *op_desc;
  23.     };
  24.  
  25.     struct op_entry table[] =
  26.     {
  27.         {"nop",  "do nothing"},
  28.         {"aconst_null",  "push null"},
  29.         {"iconst_m1",  "push int constant -1"},
  30.         {"iconst_0",  "push int constant 0"},
  31.         {"iconst_1",  "push int constant 1"},
  32.         {"iconst_2",  "push int constant 2"},
  33.         {"iconst_3",  "push int constant 3"},
  34.         {"iconst_4",  "push int constant 4"},
  35.         {"iconst_5",  "push int constant 5"},
  36.         {"lconst_0",  "push long constant 0"},
  37.         {"lconst_1",  "push long constant 1"},
  38.         {"fconst_0",  "push float 0.0"},
  39.         {"fconst_1",  "push float 1.0"},
  40.         {"fconst_2",  "push float 2.0"},
  41.         {"dconst_0",  "push double 0.0 onto stack"},
  42.         {"dconst_1",  "push double 1.0 onto stack"},
  43.         {"bipush",  "push byte"},
  44.         {"sipush",  "push short"},
  45.         {"ldc",  "push item from constant pool"},
  46.         {"ldc_w",  "push item from constant pool (wide index)"},
  47.         {"ldc2_w",  "push long or double from constant pool (wide index)"},
  48.         {"iload",  "load int from local variable"},
  49.         {"lload",  "load long from local variable"},
  50.         {"fload",  "load float from local variable"},
  51.         {"dload",  "load double from local variable"},
  52.         {"aload",  "load reference from local variable"},
  53.         {"iload_0",  "load int from local variable 0"},
  54.         {"iload_1",  "load int from local variable 1"},
  55.         {"iload_2",  "load int from local variable 2"},
  56.         {"iload_3",  "load int from local variable 3"},
  57.         {"lload_0",  "load long from local variable 0"},
  58.         {"lload_1",  "load long from local variable 1"},
  59.         {"lload_2",  "load long from local variable 2"},
  60.         {"lload_3",  "load long from local variable 3"},
  61.         {"fload_0",  "load float from local variable 0"},
  62.         {"fload_1",  "load float from local variable 1"},
  63.         {"fload_2",  "load float from local variable 2"},
  64.         {"fload_3",  "load float from local variable 3"},
  65.         {"dload_0",  "load double from local variable 0"},
  66.         {"dload_1",  "load double from local variable 1"},
  67.         {"dload_2",  "load double from local variable 2"},
  68.         {"dload_3",  "load double from local variable 3"},
  69.         {"aload_0",  "load reference from local variable 0"},
  70.         {"aload_1",  "load reference from local variable 1"},
  71.         {"aload_2",  "load reference from local variable 2"},
  72.         {"aload_3",  "load reference from local variable 3"},
  73.         {"iaload",  "load int from array"},
  74.         {"laload",  "load long from array"},
  75.         {"faload",  "load float from array"},
  76.         {"daload",  "load double from array"},
  77.         {"aaload",  "load reference from array"},
  78.         {"baload",  "load byte from array"},
  79.         {"caload",  "load char from array"},
  80.         {"saload",  "load short from array"},
  81.         {"istore",  "store int into local variable"},
  82.         {"lstore",  "store long into local variable"},
  83.         {"fstore",  "store float into local variable"},
  84.         {"dstore",  "store double into local variable"},
  85.         {"astore",  "store reference into local variable"},
  86.         {"istore_0",  "store int into local variable 0"},
  87.         {"istore_1",  "store int into local variable 1"},
  88.         {"istore_2",  "store int into local variable 2"},
  89.         {"istore_3",  "store int into local variable 3"},
  90.         {"lstore_0",  "store long into local variable 0"},
  91.         {"lstore_1",  "store long into local variable 1"},
  92.         {"lstore_2",  "store long into local variable 2"},
  93.         {"lstore_3",  "store long into local variable 3"},
  94.         {"fstore_0",  "store float into local variable 0"},
  95.         {"fstore_1",  "store float into local variable 1"},
  96.         {"fstore_2",  "store float into local variable 2"},
  97.         {"fstore_3",  "store float into local variable 3"},
  98.         {"dstore_0",  "store double into local variable 0"},
  99.         {"dstore_1",  "store double into local variable 1"},
  100.         {"dstore_2",  "store double into local variable 2"},
  101.         {"dstore_3",  "store double into local variable 3"},
  102.         {"astore_0",  "store reference into local variable 0"},
  103.         {"astore_1",  "store reference into local variable 1"},
  104.         {"astore_2",  "store reference into local variable 2"},
  105.         {"astore_3",  "store reference into local variable 3"},
  106.         {"iastore",  "store into int array"},
  107.         {"lastore",  "store into long array"},
  108.         {"fastore",  "store into float array"},
  109.         {"dastore",  "store into double array"},
  110.         {"aastore",  "store into reference array"},
  111.         {"bastore",  "store into byte array"},
  112.         {"castore",  "store into char array"},
  113.         {"sastore",  "store into short array"},
  114.         {"pop",  "pop top operand stack word"},
  115.         {"pop2",  "pop two two operand stack words"},
  116.         {"dup",  "duplicate top operand stack word"},
  117.         {"dup_x1",  "duplicate top operand stack word and put two down"},
  118.         {"dup_x2",  "duplicate top operand stack word and put three down"},
  119.         {"dup2",  "duplicate top two operand stack words"},
  120.         {"dup2_x1",  "duplicate top two operand stack words and put three down"},
  121.         {"dup2_x2",  "duplicate top two operand stack words and put four down"},
  122.         {"swap",  "swap top two operand stack words"},
  123.         {"iadd",  "add int"},
  124.         {"ladd",  "add long"},
  125.         {"fadd",  "add float"},
  126.         {"dadd",  "add double"},
  127.         {"isub",  "subtract int"},
  128.         {"lsub",  "subtract long"},
  129.         {"fsub",  "substract float"},
  130.         {"dsub",  "subtract double"},
  131.         {"imul",  "multiply int"},
  132.         {"lmul",  "multiply long"},
  133.         {"fmul",  "multiply float"},
  134.         {"dmul",  "multiply double"},
  135.         {"idiv",  "divide int"},
  136.         {"ldiv",  "divide long"},
  137.         {"fdiv",  "divide float"},
  138.         {"ddiv",  "divide double"},
  139.         {"irem",  "remainder int"},
  140.         {"lrem",  "remainder long"},
  141.         {"frem",  "remainder float"},
  142.         {"drem",  "remainder double"},
  143.         {"ineg",  "negate int"},
  144.         {"lneg",  "negate long"},
  145.         {"fneg",  "negate float"},
  146.         {"dneg",  "negate double"},
  147.         {"ishl",  "shift left int"},
  148.         {"lshl",  "shift left long"},
  149.         {"ishr",  "shift right int"},
  150.         {"lshr",  "shift right long"},
  151.         {"iushr",  "logical shift right int"},
  152.         {"lushr",  "logical shift right long"},
  153.         {"iand",  "boolean and int"},
  154.         {"land",  "boolean and long"},
  155.         {"ior",  "boolean or int"},
  156.         {"lor",  "boolean or long"},
  157.         {"ixor",  "boolean xor int"},
  158.         {"lxor",  "boolean xor long"},
  159.         {"iinc",  "increment local variable by constant"},
  160.         {"i2l",  "convert int to long"},
  161.         {"i2f",  "convert int to float"},
  162.         {"i2d",  "convert int to double"},
  163.         {"l2i",  "convert long to int"},
  164.         {"l2f",  "convert long to float"},
  165.         {"l2d",  "convert long to double"},
  166.         {"f2i",  "convert float to int"},
  167.         {"f2l",  "convert float to long"},
  168.         {"f2d",  "convert float to double"},
  169.         {"d2i",  "convert double to int"},
  170.         {"d2l",  "convert double to long"},
  171.         {"d2f",  "convert double to float"},
  172.         {"i2b",  "convert int to byte"},
  173.         {"i2c",  "convert int to char"},
  174.         {"i2s",  "convert int to short"},
  175.         {"lcmp",  "compare long"},
  176.         {"fcmpl",  "compare float less"},
  177.         {"fcmpg",  "compare float greater"},
  178.         {"dcmpl",  "compare double less"},
  179.         {"dcmpg",  "compare double greater"},
  180.         {"ifeq",  "branch if int eq zero"},
  181.         {"ifne",  "branch if int ne zero"},
  182.         {"iflt",  "branch if int lt zero"},
  183.         {"ifge",  "branch if int ge zero"},
  184.         {"ifgt",  "branch if int gt zero"},
  185.         {"ifle",  "branch if int le zero"},
  186.         {"if_icmpeq",  "branch if int comparison eq"},
  187.         {"if_icmpne",  "branch if int comparison ne"},
  188.         {"if_icmplt",  "branch if int comparison lt"},
  189.         {"if_icmpge",  "branch if int comparison ge"},
  190.         {"if_icmpgt",  "branch if int comparison gt"},
  191.         {"if_icmple",  "branch if int comparison le"},
  192.         {"if_acmpeq",  "branch if reference comparison eq"},
  193.         {"if_acmpne",  "branch if reference comparison ne"},
  194.         {"goto",  "branch always"},
  195.         {"jsr",  "jump subroutine"},
  196.         {"ret",  "return from subroutine"},
  197.         {"tableswitch",  "access jump table by index and jump"},
  198.         {"lookupswitch",  "access jump table by key match and jump"},
  199.         {"ireturn",  "return int from method"},
  200.         {"lreturn",  "return long from method"},
  201.         {"freturn",  "return float from method"},
  202.         {"dreturn",  "return double from method"},
  203.         {"areturn",  "return reference from method"},
  204.         {"return",  "return void from method"},
  205.         {"getstatic",  "get static field from class"},
  206.         {"putstatic",  "set static field in class"},
  207.         {"getfield",  "fetch field from object"},
  208.         {"putfield",  "set field in object"},
  209.         {"invokevirtual",  "invoke instance method; dispatch based on runtime type"},
  210.         {"invokenonvirtual",  "invoke instance method; dispatch based on compile-time type"},
  211.         {"invokestatic",  "invoke a class (static) method"},
  212.         {"invokeinterface",  "invoke interface method"},
  213.         {"xxxunusedxxx",  "xxxunusedxxx"},
  214.         {"new",  "create new object"},
  215.         {"newarray",  "create new array"},
  216.         {"anewarray",  "create new array of references"},
  217.         {"arraylength",  "get length of array"},
  218.         {"athrow",  "throw exception or error"},
  219.         {"checkcast",  "check whether object is of given type"},
  220.         {"instanceof",  "determine if object is of given type"},
  221.         {"monitorenter",  "enter monitor for object"},
  222.         {"monitorexit",  "exit monitor for object"},
  223.         {"wide",  "extend local variable index by additional bytes"},
  224.         {"multianewarray",  "create new multidimensional array"},
  225.         {"ifnull",  "branch if reference is null"},
  226.         {"ifnonnuull",  "branch if reference not null"},
  227.         {"goto_w",  "branch always (wide index) ?"},
  228.         {"jsr_w",  "jump subroutine (wide index)"}
  229.     };
  230.  
  231.     if (opc == OP_SOFTWARE)                 // software
  232.          *name = *desc = "software";
  233.     else if (opc == OP_HARDWARE)           // hardware
  234.          *name = *desc = "hardware";
  235.     else if (opc >=0 && opc <= 0xc9)
  236.     {
  237.          *name = table[opc].op_name;
  238.          *desc = table[opc].op_desc;
  239.     }
  240.     else *name = *desc = "illegal";
  241.  
  242.      return;
  243. }
  244.  
  245. void Operators::opline(Tuple<cp_info *> &constant_pool, char *hdr, int pc, int opc, char *name,
  246.                        char *args, char *desc, int info_kind, int info_index)
  247. {
  248.     // generate line of opcode dump, info is extra info
  249.  
  250.     Coutput << *hdr;
  251.     Coutput.width(4);
  252.     Coutput << pc;
  253.     Coutput << "\t" << name;
  254.     int len = strlen(name);
  255.     if (strlen(args))
  256.     {
  257.         Coutput << " " << args;
  258.         len += (strlen(args) + 1);
  259.     }
  260.     if (len < 8)
  261.          Coutput << "\t\t\t";
  262.     else if (len < 16)
  263.          Coutput << "\t\t";
  264.     else Coutput << "\t";
  265.  
  266.     switch (info_kind)
  267.     {
  268.         case INFO_CONST:
  269.              Coutput << " ";
  270.              if (info_index <= 0 || info_index > constant_pool.Length())
  271.                 Coutput << "OUT-OF_BOUNDS CONSTANT_POOL-INDEX " << info_index;
  272.             else {
  273. //              constant_pool[info_index] -> describe(constant_pool);
  274.             }
  275.             break;
  276.         case INFO_LOCAL:
  277.             Coutput << " local#" << info_index;
  278.             break;
  279.     }
  280. //
  281. // DS (17 jun) - skip desc for now: it's too long and shoud only
  282. // be written at user request.
  283. //  Coutput << " " << desc;
  284. //
  285.     Coutput << "\n";
  286.  
  287.     return;
  288. }
  289.  
  290. void Operators::opdmp(Tuple<cp_info *> &constant_pool, Tuple<u1> &code)
  291. {
  292.     int pc = 0;
  293.     while (pc < code.Length())
  294.     {
  295.         int info_kind = INFO_NONE; // assume no extra info
  296.         int info_index = 0;
  297.         int pc_start = pc;
  298.         unsigned opc = get_u1(code, pc);
  299.         char *name, *desc; // set to name (mnemonic) and description of opcode.
  300.         opdesc(code[pc_start], &name, &desc);
  301.         pc++;
  302.  
  303.         char argdesc[100];
  304.         argdesc[0] = U_NULL; // assume no argument description needed
  305.  
  306.         unsigned au1;
  307.         int ai1,
  308.             ai2,
  309.             ai4;
  310.         switch (opc)
  311.         {
  312.             case OP_BIPUSH:
  313.                  ai1 = get_i1(code, pc); pc++;
  314.                  sprintf(argdesc, "%d", ai1);
  315.                  break;
  316.             case OP_SIPUSH:
  317.                  ai2 = get_i2(code, pc); pc +=2;
  318.                  sprintf(argdesc, "%d", ai2);
  319.                  break;
  320.             case OP_LDC:
  321.                  info_index = get_u1(code, pc); pc++;
  322.                  sprintf(argdesc,"%d", info_index);
  323.                  info_kind = INFO_CONST;
  324.                  break;
  325.             case OP_LDC_W:
  326.             case OP_LDC2_W:
  327.                  info_index = get_u2(code, pc);pc +=2;
  328.                  sprintf(argdesc, "%u", info_index);
  329.                  info_kind = INFO_CONST;
  330.                  break;
  331.             case OP_ILOAD:
  332.             case OP_LLOAD:
  333.             case OP_FLOAD:
  334.             case OP_DLOAD:
  335.             case OP_ALOAD:
  336.             case OP_ISTORE:
  337.             case OP_LSTORE:
  338.             case OP_FSTORE:
  339.             case OP_DSTORE:
  340.             case OP_ASTORE:
  341.                  info_index = get_u1(code, pc);pc++;
  342.                  sprintf(argdesc, "%u", info_index);
  343.                  info_kind = INFO_LOCAL;
  344.                  break;
  345.             case OP_ILOAD_0:
  346.             case OP_LLOAD_0:
  347.             case OP_FLOAD_0:
  348.             case OP_DLOAD_0:
  349.             case OP_ALOAD_0:
  350.             case OP_ISTORE_0:
  351.             case OP_LSTORE_0:
  352.             case OP_FSTORE_0:
  353.             case OP_DSTORE_0:
  354.             case OP_ASTORE_0:
  355.                  info_kind = INFO_LOCAL;
  356.                  info_index = 0;
  357.                  break;
  358.             case OP_ILOAD_1:
  359.             case OP_LLOAD_1:
  360.             case OP_FLOAD_1:
  361.             case OP_DLOAD_1:
  362.             case OP_ALOAD_1:
  363.             case OP_ISTORE_1:
  364.             case OP_LSTORE_1:
  365.             case OP_FSTORE_1:
  366.             case OP_DSTORE_1:
  367.             case OP_ASTORE_1:
  368.                  info_kind = INFO_LOCAL;
  369.                  info_index = 1;
  370.                  break;
  371.             case OP_ILOAD_2:
  372.             case OP_LLOAD_2:
  373.             case OP_FLOAD_2:
  374.             case OP_DLOAD_2:
  375.             case OP_ALOAD_2:
  376.             case OP_ISTORE_2:
  377.             case OP_LSTORE_2:
  378.             case OP_DSTORE_2:
  379.             case OP_FSTORE_2:
  380.             case OP_ASTORE_2:
  381.                  info_kind = INFO_LOCAL;
  382.                  info_index = 2;
  383.                  break;
  384.             case OP_ILOAD_3:
  385.             case OP_LLOAD_3:
  386.             case OP_FLOAD_3:
  387.             case OP_DLOAD_3:
  388.             case OP_ALOAD_3:
  389.             case OP_ISTORE_3:
  390.             case OP_LSTORE_3:
  391.             case OP_FSTORE_3:
  392.             case OP_DSTORE_3:
  393.             case OP_ASTORE_3:
  394.                  info_kind= INFO_LOCAL;
  395.                  info_index = 3;
  396.                  break;
  397.             case OP_IINC:
  398.                  info_index = get_u1(code, pc); pc++;
  399.                  au1 = get_u1(code, pc); pc++;
  400.                  ai1 = get_i1(code, pc); pc++;
  401.                  info_kind = INFO_LOCAL;
  402.                  sprintf(argdesc, "%d %d", au1, ai1);
  403.                  break;
  404.             case OP_IFEQ:
  405.             case OP_IFNE:
  406.             case OP_IFLT:
  407.             case OP_IFGE:
  408.             case OP_IFGT:
  409.             case OP_IFLE:
  410.             case OP_IF_ICMPEQ:
  411.             case OP_IF_ICMPNE:
  412.             case OP_IF_ICMPLT:
  413.             case OP_IF_ICMPGE:
  414.             case OP_IF_ICMPGT:
  415.             case OP_IF_ICMPLE:
  416.             case OP_IF_ACMPEQ:
  417.             case OP_IF_ACMPNE:
  418.             case OP_GOTO:
  419.             case OP_JSR:
  420.             case OP_IFNULL:
  421.             case OP_IFNONNULL:
  422.                  ai2 = get_i2(code, pc);
  423.                  sprintf(argdesc, "%d", (int) ( ai2+pc_start)); // compute branch target
  424.                  pc +=2;
  425.                  break;
  426.             case OP_RET:
  427.                  au1 = get_u1(code, pc);
  428.                  pc++;
  429.                  sprintf(argdesc, "%d", (int) au1);
  430.                  break;
  431.             case OP_TABLESWITCH:
  432.                  {
  433.                      int def,
  434.                          low,
  435.                          high,
  436.                          len,
  437.                          val,
  438.                          pc_this,
  439.                          op_this;
  440.                      unsigned iu1;
  441.                      op_this = OP_TABLESWITCH;
  442.                      // account for padding
  443.                      while (pc % 4)
  444.                      {
  445.                          iu1 = get_u1(code, pc);
  446.                          pc++;
  447.                      }
  448.                      def = get_i4(code, pc); pc += 4;
  449.                      low = get_i4(code, pc); pc +=4;
  450.                      high = get_i4(code, pc); pc += 4;
  451.                      sprintf(argdesc, "default:%d low:%d high:%d", def + pc_start, low, high);
  452.                      opline(constant_pool, " ", pc_start, opc, name, argdesc, desc, info_kind, info_index);
  453.                      len =  high - low + 1;
  454.                      while (len)
  455.                      {
  456.                          pc_this = pc;
  457.                          val = get_i4(code, pc);
  458.                          sprintf(argdesc, "match:%d offset:%d", low++, val + pc_start);
  459.                          opline(constant_pool,"*",pc_this, op_this,name,argdesc,desc,INFO_NONE,0);
  460.                          pc += 4;
  461.                          len--;
  462.                      }
  463.                      info_kind = INFO_DONE;
  464.                  }
  465.                  break;
  466.             case OP_LOOKUPSWITCH:
  467.                  {
  468.                      int def,
  469.                          npairs,
  470.                          len,
  471.                          match,
  472.                          offset,
  473.                          op_this;
  474.  
  475.                      // account for padding
  476.                      unsigned iu1;
  477.                      op_this = OP_LOOKUPSWITCH;
  478.                      while (pc % 4)
  479.                      {
  480.                          iu1 = get_u1(code, pc);
  481.                          pc++;
  482.                      }
  483.                      def = get_i4(code, pc); pc += 4;
  484.                      npairs = get_i4(code, pc); pc +=4;
  485.                      sprintf(argdesc, "default:%d npairs:%d", (def + pc_start), npairs);
  486.                      opline(constant_pool, " ", pc_start, op_this, name, argdesc, desc, info_kind, info_index);
  487.                      len = npairs;
  488.                      while (npairs)
  489.                      {
  490.                          int pcb = pc;
  491.                          match = get_i4(code, pc); pc +=4 ;
  492.                          offset = get_i4(code, pc); pc +=4;
  493.                          sprintf(argdesc, "match:%d offset:%d ", match,offset + pc_start);
  494.                          opline(constant_pool, "*", pcb, op_this, name, argdesc, desc, INFO_NONE, 0);
  495.                          npairs--;
  496.                      }
  497.                      info_kind = INFO_DONE;
  498.                  }
  499.                  break;
  500.             case OP_GETSTATIC:
  501.             case OP_PUTSTATIC:
  502.             case OP_GETFIELD:
  503.             case OP_PUTFIELD:
  504.             case OP_INVOKEVIRTUAL:
  505.             case OP_INVOKENONVIRTUAL:
  506.             case OP_INVOKESTATIC:
  507.             case OP_NEW:
  508.             case OP_ANEWARRAY:
  509.             case OP_CHECKCAST:
  510.             case OP_INSTANCEOF:
  511.                  info_index = get_u2(code, pc); pc += 2;
  512.                  sprintf(argdesc, "%d", info_index);
  513.                  info_kind = INFO_CONST;
  514.                  break;
  515.             case OP_INVOKEINTERFACE:
  516.                  {
  517.                      int nargs;
  518.                      info_index = get_u2(code, pc); pc += 2;
  519.                      au1 = get_u1(code, pc); pc++;
  520.                      nargs = au1;
  521.                      au1 = get_u1(code, pc); pc++;
  522.  
  523.                      assert((! au1) && "...zero byte required in this position");
  524.  
  525.                      sprintf(argdesc, "%d %d", nargs,info_index);
  526.                      info_kind=INFO_CONST;
  527.                  }
  528.                  break;
  529.             case OP_NEWARRAY:
  530.                  au1 = get_u1(code, pc); pc++;
  531.                  switch(au1)
  532.                  {
  533.                      case 4: sprintf(argdesc, "%s", "BOOLEAN");break;
  534.                      case 5: sprintf(argdesc, "%s", "CHAR");break;
  535.                      case 6: sprintf(argdesc, "%s", "FLOAT");break;
  536.                      case 7: sprintf(argdesc, "%s", "DOUBLE");break;
  537.                      case 8: sprintf(argdesc, "%s", "BYTE");break;
  538.                      case 9: sprintf(argdesc, "%s", "SHORT");break;
  539.                      case 10: sprintf(argdesc, "%s", "INT");break;
  540.                      case 11: sprintf(argdesc, "%s", "LONG");break;
  541.                      default:
  542.                          sprintf(argdesc, "%s", "<UNKNOWN>");break;
  543.                  }
  544.                  break;
  545.             case OP_WIDE:
  546.                  assert(false && "dmp for op_wide not supported yet");
  547.                  break;
  548.             case OP_MULTIANEWARRAY:
  549.                  info_index = get_u2(code, pc); pc += 2;
  550.                  au1 = get_u1(code, pc); pc++;
  551.                  info_kind = INFO_CONST;
  552.                  // au1 gives dimensions
  553.                  sprintf(argdesc, "%u", au1);
  554.                  break;
  555.             case OP_GOTO_W:
  556.             case OP_JSR_W:
  557.                  ai4 = get_i4(code, pc); pc += 4;
  558.                  // ai4 gives offset (wide) of branch target
  559.                  sprintf(argdesc, "%d", pc_start + ai4);
  560.                  break;
  561.             default:
  562.                  break;
  563.         }
  564.  
  565.         // output first part of description
  566.         if (info_kind != INFO_DONE)
  567.             opline(constant_pool, " ", pc_start, opc, name, argdesc, desc, info_kind, info_index);
  568.     }
  569.  
  570.     return;
  571. }
  572.  
  573.  
  574. //
  575. // stack_effect gives effect on stack of executing an opcode
  576. //
  577. int Operators::stack_effect[] =
  578. {
  579.     0,  // OP_NOP
  580.     1,  // OP_ACONST_NULL
  581.     1,  // OP_ICONST_M1
  582.     1,  // OP_ICONST_0
  583.     1,  // OP_ICONST_1
  584.     1,  // OP_ICONST_2
  585.     1,  // OP_ICONST_3
  586.     1,  // OP_ICONST_4
  587.     1,  // OP_ICONST_5
  588.     2,  // OP_LCONST_0
  589.     2,  // OP_LCONST_1
  590.     1,  // OP_FCONST_0
  591.     1,  // OP_FCONST_1
  592.     1,  // OP_FCONST_2
  593.     2,  // OP_DCONST_0
  594.     2,  // OP_DCONST_1
  595.     1,  // OP_BIPUSH
  596.     1,  // OP_SIPUSH
  597.     1,  // OP_LDC
  598.     1,  // OP_LDC_W
  599.     2,  // OP_LDC2_W
  600.     1,  // OP_ILOAD
  601.     2,  // OP_LLOAD
  602.     1,  // OP_FLOAD
  603.     2,  // OP_DLOAD
  604.     1,  // OP_ALOAD
  605.     1,  // OP_ILOAD_0
  606.     1,  // OP_ILOAD_1
  607.     1,  // OP_ILOAD_2
  608.     1,  // OP_ILOAD_3
  609.     2,  // OP_LLOAD_0
  610.     2,  // OP_LLOAD_1
  611.     2,  // OP_LLOAD_2
  612.     2,  // OP_LLOAD_3
  613.     1,  // OP_FLOAD_0
  614.     1,  // OP_FLOAD_1
  615.     1,  // OP_FLOAD_2
  616.     1,  // OP_FLOAD_3
  617.     2,  // OP_DLOAD_0
  618.     2,  // OP_DLOAD_1
  619.     2,  // OP_DLOAD_2
  620.     2,  // OP_DLOAD_3
  621.     1,  // OP_ALOAD_0
  622.     1,  // OP_ALOAD_1
  623.     1,  // OP_ALOAD_2
  624.     1,  // OP_ALOAD_3
  625.    -1,  // OP_IALOAD
  626.     0,  // OP_LALOAD
  627.    -1,  // OP_FALOAD
  628.     0,  // OP_DALOAD
  629.    -1,  // OP_AALOAD
  630.    -1,  // OP_BALOAD
  631.    -1,  // OP_CALOAD
  632.    -1,  // OP_SALOAD
  633.    -1,  // OP_ISTORE
  634.    -2,  // OP_LSTORE
  635.    -1,  // OP_FSTORE
  636.    -2,  // OP_DSTORE
  637.    -1,  // OP_ASTORE
  638.    -1,  // OP_ISTORE_0
  639.    -1,  // OP_ISTORE_1
  640.    -1,  // OP_ISTORE_2
  641.    -1,  // OP_ISTORE_3
  642.    -2,  // OP_LSTORE_0
  643.    -2,  // OP_LSTORE_1
  644.    -2,  // OP_LSTORE_2
  645.    -2,  // OP_LSTORE_3
  646.    -1,  // OP_FSTORE_0
  647.    -1,  // OP_FSTORE_1
  648.    -1,  // OP_FSTORE_2
  649.    -1,  // OP_FSTORE_3
  650.    -2,  // OP_DSTORE_0
  651.    -2,  // OP_DSTORE_1
  652.    -2,  // OP_DSTORE_2
  653.    -2,  // OP_DSTORE_3
  654.    -1,  // OP_ASTORE_0
  655.    -1,  // OP_ASTORE_1
  656.    -1,  // OP_ASTORE_2
  657.    -1,  // OP_ASTORE_3
  658.    -3,  // OP_IASTORE
  659.    -4,  // OP_LASTORE
  660.    -3,  // OP_FASTORE
  661.    -4,  // OP_DASTORE
  662.    -3,  // OP_AASTORE
  663.    -3,  // OP_BASTORE
  664.    -3,  // OP_CASTORE
  665.    -3,  // OP_SASTORE
  666.    -1,  // OP_POP
  667.    -2,  // OP_POP2
  668.     1,  // OP_DUP
  669.     1,  // OP_DUP_X1
  670.     1,  // OP_DUP_X2
  671.     2,  // OP_DUP2
  672.     2,  // OP_DUP2_X1
  673.     2,  // OP_DUP2_X2
  674.     0,  // OP_SWAP
  675.    -1,  // OP_IADD
  676.    -2,  // OP_LADD
  677.    -1,  // OP_FADD
  678.    -2,  // OP_DADD
  679.    -1,  // OP_ISUB
  680.    -2,  // OP_LSUB
  681.    -1,  // OP_FSUB
  682.    -2,  // OP_DSUB
  683.    -1,  // OP_IMUL
  684.    -2,  // OP_LMUL
  685.    -1,  // OP_FMUL
  686.    -2,  // OP_DMUL
  687.    -1,  // OP_IDIV
  688.    -2,  // OP_LDIV
  689.    -1,  // OP_FDIV
  690.    -2,  // OP_DDIV
  691.    -1,  // OP_IREM
  692.    -2,  // OP_LREM
  693.    -1,  // OP_FREM
  694.    -2,  // OP_DREM
  695.     0,  // OP_INEG
  696.     0,  // OP_LNEG
  697.     0,  // OP_FNEG
  698.     0,  // OP_DNEG
  699.    -1,  // OP_ISHL
  700.    -1,  // OP_LSHL
  701.    -1,  // OP_ISHR
  702.    -1,  // OP_LSHR
  703.    -1,  // OP_IUSHR
  704.    -1,  // OP_LUSHR
  705.    -1,  // OP_IAND
  706.    -2,  // OP_LAND
  707.    -1,  // OP_IOR
  708.    -2,  // OP_LOR
  709.    -1,  // OP_IXOR
  710.    -2,  // OP_LXOR
  711.     0,  // OP_IINC
  712.     1,  // OP_I2L
  713.     0,  // OP_I2F
  714.     1,  // OP_I2D
  715.    -1,  // OP_L2I
  716.    -1,  // OP_L2F
  717.     0,  // OP_L2D
  718.     0,  // OP_F2I
  719.     1,  // OP_F2L
  720.     1,  // OP_F2D
  721.    -1,  // OP_D2I
  722.     0,  // OP_D2L
  723.    -1,  // OP_D2F
  724.     0,  // OP_I2B
  725.     0,  // OP_I2C
  726.     0,  // OP_I2S
  727.    -3,  // OP_LCMP
  728.    -1,  // OP_FCMPL
  729.    -1,  // OP_FCMPG
  730.    -3,  // OP_DCMPL
  731.    -3,  // OP_DCMPG
  732.    -1,  // OP_IFEQ
  733.    -1,  // OP_IFNE
  734.    -1,  // OP_IFLT
  735.    -1,  // OP_IFGE
  736.    -1,  // OP_IFGT
  737.    -1,  // OP_IFLE
  738.    -2,  // OP_IF_ICMPEQ
  739.    -2,  // OP_IF_ICMPNE
  740.    -2,  // OP_IF_ICMPLT
  741.    -2,  // OP_IF_ICMPGE
  742.    -2,  // OP_IF_ICMPGT
  743.    -2,  // OP_IF_ICMPLE
  744.    -2,  // OP_IF_ACMPEQ
  745.    -2,  // OP_IF_ACMPNE
  746.     0,  // OP_GOTO
  747.     1,  // OP_JSR
  748.     0,  // OP_RET
  749.    -1,  // OP_TABLESWITCH
  750.    -1,  // OP_LOOKUPSWITCH
  751.    -1,  // OP_IRETURN
  752.    -2,  // OP_LRETURN
  753.    -1,  // OP_FRETURN
  754.    -2,  // OP_DRETURN
  755.    -1,  // OP_ARETURN
  756.     0,  // OP_RETURN
  757.     0,  // OP_GETSTATIC, caller must adjust if long or double
  758.     0,  // OP_PUTSTATIC, caller must adjust if long or double
  759.     0,  // OP_GETFIELD, caller must adjust if long or double
  760.     0,  // OP_PUTFIELD, caller must adjust if long or double
  761.    -1,  // OP_INVOKEVIRTUAL,   actually  -1-args_length
  762.    -1,  // OP_INVOKENONVIRTUAL,    actually  -1-args_length
  763.     0,  // OP_INVOKESTATIC, actually -args_length
  764.    -1,  // OP_INVOKEINTERFACE, actually -1 -args_length
  765.     0,  // OP_XXXUNUSEDXXX
  766.     1,  // OP_NEW
  767.     0,  // OP_NEWARRAY
  768.     0,  // OP_ANEWARRAY
  769.     0,  // OP_ARRAYLENGTH
  770.     0,  // OP_ATHROW
  771.     0,  // OP_CHECKCAST
  772.     0,  // OP_INSTANCEOF
  773.    -1,  // OP_MONITORENTER
  774.    -1,  // OP_MONITOREXIT
  775.     0,  // OP_WIDE
  776.     0,  // OP_MULTIANEWARRAY, actually dims-1
  777.    -1,  // OP_IFNULL
  778.    -1,  // OP_IFNONNULL
  779.     0,  // OP_GOTO_W
  780.     1,  // OP_JSR_W
  781.     0,  // OP_SOFTWARE
  782.     0   // OP_HARDWARE
  783. };
  784.